package org.fast.develop.logicflow.runtime.expression;

/**
 * 项 目 名：gs-tto-data-mapping
 * 源文件名：com.geekstorm.tto.datamapping.core.expression.VariableScopeElResolver
 * 文件版本：1.0.0
 * 创建人： 莫寅
 * 创建日期：2020-07-23 11:43
 * 修改作者：莫寅
 * 修改日期：2020-07-23 11:43
 * 文件描述：
 * By：2020 © CompanyName  , Inc. All Rights Reserved.
 */

import javax.el.ELContext;
import javax.el.ELResolver;
import java.beans.FeatureDescriptor;
import java.util.Iterator;

/**
 * Implementation of an {@link ELResolver} that resolves expressions with the process
 * variables of a given {@link VariableScope} as context. <br>
 * Also exposes the currently logged in username to be used in expressions (if any)
 *
 * @author Joram Barrez
 * @author Frederik Heremans
 */
public class VariableScopeElResolver extends ELResolver {

	protected VariableScope variableScope;

	public VariableScopeElResolver(VariableScope variableScope) {
		this.variableScope = variableScope;
	}

	@Override
	public Object getValue(ELContext context, Object base, Object property) {

		if (base == null) {
			String variable = (String) property; // according to javadoc, can only be a
													// String

			if (variableScope.hasVariable(variable)) {
				context.setPropertyResolved(true); // if not set, the next elResolver in
													// the CompositeElResolver will be
													// called
				return variableScope.getVariable(variable);
			}
		}

		// property resolution (eg. bean.value) will be done by the
		// BeanElResolver (part of the CompositeElResolver)
		// It will use the bean resolved in this resolver as base.

		return null;
	}

	@Override
	public boolean isReadOnly(ELContext context, Object base, Object property) {
		if (base == null) {
			String variable = (String) property;
			return !variableScope.hasVariable(variable);
		}
		return true;
	}

	@Override
	public void setValue(ELContext context, Object base, Object property, Object value) {
		if (base == null) {
			String variable = (String) property;
			if (variableScope.hasVariable(variable)) {
				variableScope.setVariable(variable, value);
			}
		}
	}

	@Override
	public Class<?> getCommonPropertyType(ELContext arg0, Object arg1) {
		return Object.class;
	}

	@Override
	public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext arg0, Object arg1) {
		return null;
	}

	@Override
	public Class<?> getType(ELContext arg0, Object arg1, Object arg2) {
		return Object.class;
	}

}
